```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深入理解Java ByteBuffer | 技术小馆</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8f9fa;
            color: #333;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
            color: white;
        }
        .code-block {
            background-color: #282c34;
            border-left: 4px solid #6e8efb;
        }
        .card {
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 20px rgba(0,0,0,0.1);
        }
        .nav-link {
            position: relative;
        }
        .nav-link::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 0;
            width: 0;
            height: 2px;
            background-color: #6e8efb;
            transition: width 0.3s ease;
        }
        .nav-link:hover::after {
            width: 100%;
        }
        .diagram-container {
            background-color: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>
    <!-- 导航栏 -->
    <nav class="bg-white shadow-sm py-4 sticky top-0 z-50">
        <div class="container mx-auto px-4 flex justify-between items-center">
            <div class="flex items-center space-x-2">
                <i class="fas fa-code text-2xl text-indigo-600"></i>
                <span class="font-semibold text-xl">技术小馆</span>
            </div>
            <div class="hidden md:flex space-x-8">
                <a href="#" class="nav-link font-medium">首页</a>
                <a href="#" class="nav-link font-medium">Java</a>
                <a href="#" class="nav-link font-medium">NIO</a>
                <a href="#" class="nav-link font-medium">关于</a>
            </div>
            <button class="md:hidden text-gray-600">
                <i class="fas fa-bars text-2xl"></i>
            </button>
        </div>
    </nav>

    <!-- Hero模块 -->
    <section class="hero py-20">
        <div class="container mx-auto px-4 text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6">深入理解Java ByteBuffer</h1>
            <p class="text-xl md:text-2xl mb-8 max-w-3xl mx-auto">掌握NIO核心组件，提升高性能IO处理能力</p>
            <div class="flex justify-center space-x-4">
                <a href="#basics" class="px-6 py-3 bg-white text-indigo-600 rounded-full font-medium hover:bg-gray-100 transition">开始学习</a>
                <a href="#applications" class="px-6 py-3 border-2 border-white text-white rounded-full font-medium hover:bg-white hover:bg-opacity-10 transition">查看应用</a>
            </div>
        </div>
    </section>

    <!-- 主要内容 -->
    <main class="container mx-auto px-4 py-12">
        <!-- 目录导航 -->
        <div class="bg-white rounded-xl shadow-md p-6 mb-12 sticky top-20 z-40 hidden md:block">
            <h2 class="text-xl font-semibold mb-4 flex items-center">
                <i class="fas fa-list-ol mr-2 text-indigo-600"></i>文章目录
            </h2>
            <ul class="space-y-2">
                <li><a href="#basics" class="text-indigo-600 hover:underline">一、ByteBuffer基础</a></li>
                <li><a href="#operations" class="text-indigo-600 hover:underline">二、ByteBuffer操作详解</a></li>
                <li><a href="#advanced" class="text-indigo-600 hover:underline">三、ByteBuffer的高级特性</a></li>
                <li><a href="#applications" class="text-indigo-600 hover:underline">四、ByteBuffer在网络编程和文件IO中的应用</a></li>
            </ul>
        </div>

        <!-- 基础部分 -->
        <section id="basics" class="mb-16">
            <div class="flex items-center mb-8">
                <h2 class="text-3xl font-bold">一、ByteBuffer基础</h2>
                <div class="ml-4 px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full text-sm font-medium">基础概念</div>
            </div>

            <!-- 什么是ByteBuffer -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">1</span>
                    什么是ByteBuffer？
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer是Java NIO包中的一个核心类，它是Buffer抽象类的一个具体实现，专门用于操作字节数据。与传统的字节数组不同，ByteBuffer提供了一种更加灵活和高效的方式来处理字节数据，特别是在需要频繁读写操作的场景下。</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;

public class ByteBufferBasics {
    public static void main(String[] args) {
        // 创建一个容量为10字节的ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocate(10);
        System.out.println("初始状态:");
        printBufferStatus(buffer);
        
        // 向缓冲区写入数据
        buffer.put((byte) 1);
        buffer.put((byte) 2);
        buffer.put((byte) 3);
        System.out.println("写入3个字节后:");
        printBufferStatus(buffer);
        
        // 切换到读模式
        buffer.flip();
        System.out.println("切换到读模式后:");
        printBufferStatus(buffer);
        
        // 读取数据
        while (buffer.hasRemaining()) {
            byte b = buffer.get();
            System.out.println("读取: " + b);
        }
        
        System.out.println("读取完所有数据后:");
        printBufferStatus(buffer);
        
        // 准备再次写入数据，清除缓冲区
        buffer.clear();
        System.out.println("清除后:");
        printBufferStatus(buffer);
    }
    
    private static void printBufferStatus(ByteBuffer buffer) {
        System.out.println("position: " + buffer.position() +
                           ", limit: " + buffer.limit() +
                           ", capacity: " + buffer.capacity());
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个例子展示了ByteBuffer的基本用法：创建、写入数据、切换到读模式、读取数据，最后清除准备重用。</p>
                </div>
            </div>

            <!-- Buffer的核心属性 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">2</span>
                    Buffer的核心属性
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">理解ByteBuffer必须先掌握三个核心属性：</p>
                    <ul class="list-disc pl-6 mb-4 space-y-2">
                        <li><strong>capacity</strong>：缓冲区的最大容量，创建后不可改变</li>
                        <li><strong>position</strong>：当前位置，读/写操作都是从position开始，操作后position会自动前进</li>
                        <li><strong>limit</strong>：可访问数据的边界，在写模式下等于capacity，读模式下等于写入的数据量</li>
                    </ul>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;

public class BufferProperties {
    public static void main(String[] args) {
        // 创建缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(10);
        
        System.out.println("初始状态:");
        System.out.println("capacity: " + buffer.capacity());  // 10
        System.out.println("position: " + buffer.position());  // 0
        System.out.println("limit: " + buffer.limit());        // 10
        
        // 写入4个字节
        buffer.put((byte) 1).put((byte) 2).put((byte) 3).put((byte) 4);
        
        System.out.println("\n写入4个字节后:");
        System.out.println("capacity: " + buffer.capacity());  // 10
        System.out.println("position: " + buffer.position());  // 4
        System.out.println("limit: " + buffer.limit());        // 10
        
        // 切换到读模式
        buffer.flip();
        
        System.out.println("\n切换到读模式后:");
        System.out.println("capacity: " + buffer.capacity());  // 10
        System.out.println("position: " + buffer.position());  // 0
        System.out.println("limit: " + buffer.limit());        // 4
        
        // 读取2个字节
        buffer.get();
        buffer.get();
        
        System.out.println("\n读取2个字节后:");
        System.out.println("capacity: " + buffer.capacity());  // 10
        System.out.println("position: " + buffer.position());  // 2
        System.out.println("limit: " + buffer.limit());        // 4
        
        // 调用compact()
        buffer.compact();
        
        System.out.println("\ncompact()调用后:");
        System.out.println("capacity: " + buffer.capacity());  // 10
        System.out.println("position: " + buffer.position());  // 2
        System.out.println("limit: " + buffer.limit());        // 10
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个示例清晰地展示了操作过程中这三个属性的变化，是理解ByteBuffer工作机制的关键。</p>
                </div>
            </div>

            <!-- ByteBuffer的创建方式 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">3</span>
                    ByteBuffer的创建方式
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer提供了多种创建方式，适用于不同的场景：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;

public class CreateByteBuffer {
    public static void main(String[] args) {
        // 1. 通过allocate()在JVM堆上分配内存
        ByteBuffer heapBuffer = ByteBuffer.allocate(1024);
        System.out.println("HeapByteBuffer: " + heapBuffer.getClass().getName());
        
        // 2. 通过allocateDirect()分配直接内存（堆外）
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
        System.out.println("DirectByteBuffer: " + directBuffer.getClass().getName());
        
        // 3. 通过wrap()将字节数组包装为ByteBuffer
        byte[] bytes = new byte[1024];
        ByteBuffer wrappedBuffer = ByteBuffer.wrap(bytes);
        System.out.println("Wrapped buffer: " + wrappedBuffer.getClass().getName());
        
        // 4. 通过wrap()指定偏移量和长度
        ByteBuffer partialWrappedBuffer = ByteBuffer.wrap(bytes, 10, 100);
        System.out.println("Partially wrapped buffer position: " + partialWrappedBuffer.position());
        System.out.println("Partially wrapped buffer limit: " + partialWrappedBuffer.limit());
        
        // 比较堆内存和直接内存的性能
        System.out.println("\n性能比较:");
        long startTime = System.currentTimeMillis();
        benchmarkBuffer(heapBuffer);
        long endTime = System.currentTimeMillis();
        System.out.println("堆内存缓冲区耗时: " + (endTime - startTime) + "ms");
        
        startTime = System.currentTimeMillis();
        benchmarkBuffer(directBuffer);
        endTime = System.currentTimeMillis();
        System.out.println("直接内存缓冲区耗时: " + (endTime - startTime) + "ms");
    }
    
    private static void benchmarkBuffer(ByteBuffer buffer) {
        int iterations = 100000;
        
        for (int i = 0; i < iterations; i++) {
            buffer.clear();
            for (int j = 0; j < buffer.capacity(); j++) {
                buffer.put((byte) j);
            }
            buffer.flip();
            while (buffer.hasRemaining()) {
                buffer.get();
            }
        }
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个示例展示了创建ByteBuffer的四种主要方式，并对堆内存和直接内存的性能进行了简单比较。</p>
                </div>
            </div>
        </section>

        <!-- 操作详解 -->
        <section id="operations" class="mb-16">
            <div class="flex items-center mb-8">
                <h2 class="text-3xl font-bold">二、ByteBuffer操作详解</h2>
                <div class="ml-4 px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full text-sm font-medium">核心操作</div>
            </div>

            <!-- 基本读写操作 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">1</span>
                    基本读写操作
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer提供了丰富的方法来读写不同类型的数据：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;

public class ByteBufferOperations {
    public static void main(String[] args) {
        // 创建一个容量为100的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(100);
        
        // 写入基本类型
        buffer.put((byte) 1);           // 写入单个字节
        buffer.putChar('a');            // 写入字符（2字节）
        buffer.putInt(100);             // 写入整数（4字节）
        buffer.putLong(1000L);          // 写入长整数（8字节）
        buffer.putFloat(3.14f);         // 写入浮点数（4字节）
        buffer.putDouble(3.14159);      // 写入双精度浮点数（8字节）
        
        // 写入字节数组
        byte[] bytes = "Hello, ByteBuffer!".getBytes(StandardCharsets.UTF_8);
        buffer.put(bytes);
        
        // 切换到读模式
        buffer.flip();
        
        // 读取数据
        System.out.println("读取的字节: " + buffer.get());
        System.out.println("读取的字符: " + buffer.getChar());
        System.out.println("读取的整数: " + buffer.getInt());
        System.out.println("读取的长整数: " + buffer.getLong());
        System.out.println("读取的浮点数: " + buffer.getFloat());
        System.out.println("读取的双精度浮点数: " + buffer.getDouble());
        
        // 读取剩余的字节到一个新数组
        byte[] remaining = new byte[buffer.remaining()];
        buffer.get(remaining);
        System.out.println("读取的字符串: " + new String(remaining, StandardCharsets.UTF_8));
        
        // 使用绝对位置读写（不改变position）
        buffer.clear();
        buffer.putInt(0, 2023);  // 在索引0处放置一个整数
        System.out.println("使用绝对位置读取整数: " + buffer.getInt(0));
        
        // position不变
        System.out.println("Position: " + buffer.position());
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个示例展示了如何读写不同类型的数据，以及如何使用绝对位置进行操作，这在某些特定场景下非常有用。</p>
                </div>
            </div>

            <!-- mark和reset -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">2</span>
                    mark和reset
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer提供了mark和reset方法，用于标记当前position并在需要时恢复：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;

public class MarkResetDemo {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);
        
        // 写入数据
        for (int i = 0; i < 5; i++) {
            buffer.put((byte) i);
        }
        
        buffer.flip();  // 切换到读模式
        
        // 读取前两个字节
        System.out.println(buffer.get());  // 0
        System.out.println(buffer.get());  // 1
        
        // 标记当前位置
        buffer.mark();
        
        // 继续读取
        System.out.println(buffer.get());  // 2
        System.out.println(buffer.get());  // 3
        
        // 重置到之前标记的位置
        buffer.reset();
        
        // 再次读取，应该从标记处开始
        System.out.println("重置后再次读取:");
        System.out.println(buffer.get());  // 应该是2
        System.out.println(buffer.get());  // 应该是3
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">mark和reset在需要反复读取某段数据时非常有用，例如在网络协议解析中解析包头信息。</p>
                </div>
            </div>

            <!-- rewind、flip和clear -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">3</span>
                    rewind、flip和clear
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer提供了几个重要的方法来重置缓冲区的状态：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;

public class BufferStateReset {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);
        
        // 写入数据
        for (int i = 0; i < 5; i++) {
            buffer.put((byte) i);
        }
        
        System.out.println("写入后: position=" + buffer.position() + ", limit=" + buffer.limit());
        
        // flip(): 准备读取已写入的数据
        buffer.flip();
        System.out.println("flip()后: position=" + buffer.position() + ", limit=" + buffer.limit());
        
        // 读取2个字节
        buffer.get();
        buffer.get();
        System.out.println("读取2个字节后: position=" + buffer.position() + ", limit=" + buffer.limit());
        
        // rewind(): 倒回起始位置，可以重新读取所有数据
        buffer.rewind();
        System.out.println("rewind()后: position=" + buffer.position() + ", limit=" + buffer.limit());
        
        // 再次读取所有数据
        while (buffer.hasRemaining()) {
            System.out.print(buffer.get() + " ");
        }
        System.out.println();
        
        // clear(): 清空缓冲区，准备重新写入
        buffer.clear();
        System.out.println("clear()后: position=" + buffer.position() + ", limit=" + buffer.limit());
        
        // compact(): 压缩缓冲区，将未读取的数据移到开头
        // 先写入数据并读取部分
        for (int i = 0; i < 5; i++) {
            buffer.put((byte) i);
        }
        buffer.flip();
        buffer.get();  // 只读取一个字节
        
        System.out.println("读取一个字节后: position=" + buffer.position() + ", limit=" + buffer.limit());
        
        // 执行compact
        buffer.compact();
        System.out.println("compact()后: position=" + buffer.position() + ", limit=" + buffer.limit());
        
        // 展示compact的效果：验证数据是否正确移动
        buffer.flip();
        System.out.print("剩余数据: ");
        while (buffer.hasRemaining()) {
            System.out.print(buffer.get() + " ");
        }
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这些方法对于缓冲区的状态管理至关重要，正确使用它们可以避免常见的ByteBuffer操作错误。</p>
                </div>
            </div>
        </section>

        <!-- 高级特性 -->
        <section id="advanced" class="mb-16">
            <div class="flex items-center mb-8">
                <h2 class="text-3xl font-bold">三、ByteBuffer的高级特性</h2>
                <div class="ml-4 px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full text-sm font-medium">进阶知识</div>
            </div>

            <!-- 直接缓冲区 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">1</span>
                    直接缓冲区（Direct Buffer）与非直接缓冲区
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer有两种类型：直接缓冲区和非直接缓冲区（堆缓冲区）。它们在性能和使用场景上有显著差异：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class DirectVsHeapBuffer {
    public static void main(String[] args) throws Exception {
        // 准备测试数据
        int bufferSize = 1024 * 1024; // 1MB
        int iterations = 100;
        
        // 创建测试文件
        createTestFile("source.dat", bufferSize * iterations);
        
        // 使用堆缓冲区复制文件
        long heapTime = copyFileWithBuffer(ByteBuffer.allocate(bufferSize), 
                                         "source.dat", "heap_dest.dat");
        
        // 使用直接缓冲区复制文件
        long directTime = copyFileWithBuffer(ByteBuffer.allocateDirect(bufferSize), 
                                           "source.dat", "direct_dest.dat");
        
        System.out.println("堆缓冲区耗时: " + heapTime + "ms");
        System.out.println("直接缓冲区耗时: " + directTime + "ms");
        System.out.println("直接缓冲区相比堆缓冲区性能提升: " + 
                          String.format("%.2f%%", (heapTime - directTime) * 100.0 / heapTime));
        
        // 直接缓冲区的内存管理
        System.out.println("\n直接缓冲区内存管理示例:");
        ByteBuffer directBuffer = null;
        try {
            System.out.println("分配100MB直接内存...");
            directBuffer = ByteBuffer.allocateDirect(100 * 1024 * 1024);
            System.out.println("分配成功!");
            
            // 使用缓冲区
            directBuffer.putInt(123);
            directBuffer.flip();
            System.out.println("读取测试值: " + directBuffer.getInt());
        } catch (OutOfMemoryError e) {
            System.out.println("内存分配失败: " + e.getMessage());
        } finally {
            // 在Java 9及以上版本，可以使用以下方法主动释放直接缓冲区
            // if (directBuffer != null && directBuffer.isDirect()) {
            //     ((sun.nio.ch.DirectBuffer) directBuffer).cleaner().clean();
            // }
            System.out.println("直接缓冲区会由GC回收，但时机不确定");
        }
    }
    
    private static void createTestFile(String filename, int size) throws Exception {
        try (FileOutputStream fos = new FileOutputStream(filename);
             FileChannel channel = fos.getChannel()) {
            
            ByteBuffer buffer = ByteBuffer.allocate(64 * 1024);
            for (int i = 0; i < size / buffer.capacity(); i++) {
                buffer.clear();
                // 填充随机数据
                for (int j = 0; j < buffer.capacity(); j++) {
                    buffer.put((byte) (Math.random() * 256));
                }
                buffer.flip();
                channel.write(buffer);
            }
        }
    }
    
    private static long copyFileWithBuffer(ByteBuffer buffer, String src, String dest) throws Exception {
        long startTime = System.currentTimeMillis();
        
        try (FileInputStream fis = new FileInputStream(src);
             FileChannel srcChannel = fis.getChannel();
             FileOutputStream fos = new FileOutputStream(dest);
             FileChannel destChannel = fos.getChannel()) {
            
            int bytesRead;
            while ((bytesRead = srcChannel.read(buffer)) != -1) {
                buffer.flip();
                while (buffer.hasRemaining()) {
                    destChannel.write(buffer);
                }
                buffer.clear();
            }
        }
        
        return System.currentTimeMillis() - startTime;
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个示例比较了直接缓冲区和堆缓冲区在文件复制场景中的性能差异，并展示了直接缓冲区的内存管理特性。</p>
                </div>
            </div>

            <!-- 字节序 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">2</span>
                    字节序（Byte Order）
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer处理多字节数据类型（如int、long等）时需要考虑字节序：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class ByteOrderDemo {
    public static void main(String[] args) {
        // 检查系统默认字节序
        System.out.println("系统默认字节序: " + ByteOrder.nativeOrder());
        
        // 创建缓冲区并设置字节序
        ByteBuffer buffer = ByteBuffer.allocate(4);
        System.out.println("默认字节序: " + buffer.order());
        
        // 写入整数并查看字节序影响
        buffer.putInt(0x01020304);
        buffer.flip();
        
        // 读取单个字节，查看存储顺序
        System.out.println("默认字节序(BIG_ENDIAN)下的字节表示:");
        while (buffer.hasRemaining()) {
            System.out.print(String.format("0x%02X ", buffer.get()));
        }
        System.out.println();
        
        // 切换到小端字节序
        buffer.clear();
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        buffer.putInt(0x01020304);
        buffer.flip();
        
        System.out.println("LITTLE_ENDIAN字节序下的字节表示:");
        while (buffer.hasRemaining()) {
            System.out.print(String.format("0x%02X ", buffer.get()));
        }
        System.out.println();
        
        // 展示字节序对于读取的影响
        buffer.clear();
        buffer.order(ByteOrder.BIG_ENDIAN);
        buffer.putInt(0x01020304);
        buffer.flip();
        
        // 使用大端序读取
        System.out.println("使用BIG_ENDIAN读取整数: 0x" + Integer.toHexString(buffer.getInt()));
        
        // 使用小端序读取相同的数据
        buffer.rewind();
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        System.out.println("使用LITTLE_ENDIAN读取整数: 0x" + Integer.toHexString(buffer.getInt()));
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">在网络编程和文件格式处理中，正确处理字节序至关重要，特别是当与不同平台进行数据交换时。</p>
                </div>
            </div>

            <!-- 视图缓冲区 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">3</span>
                    视图缓冲区（View Buffer）
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer可以创建不同类型的视图缓冲区，便于操作特定类型的数据：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;

public class ViewBufferDemo {
    public static void main(String[] args) {
        // 创建ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocate(64);
        
        // 写入一些数据
        buffer.putInt(100);
        buffer.putInt(200);
        buffer.putDouble(Math.PI);
        buffer.putChar('A');
        
        // 准备读取
        buffer.flip();
        
        // 从开始位置创建各种视图缓冲区
        buffer.rewind();
        IntBuffer intView = buffer.asIntBuffer();
        System.out.println("IntBuffer内容: ");
        while (intView.hasRemaining()) {
            System.out.print(intView.get() + " ");
        }
        System.out.println();
        
        // 重新定位并创建DoubleBuffer视图
        buffer.position(8);  // 跳过前两个int（8字节）
        DoubleBuffer doubleView = buffer.asDoubleBuffer();
        System.out.println("DoubleBuffer内容: " + doubleView.get());
        
        // 创建CharBuffer视图
        buffer.position(16);  // 跳过前两个int和一个double
        CharBuffer charView = buffer.asCharBuffer();
        System.out.println("CharBuffer内容: " + charView.get());
        
        // 通过视图修改数据
        buffer.rewind();
        intView = buffer.asIntBuffer();
        intView.put(0, 500);  // 修改第一个整数
        
        // 验证原ByteBuffer中的数据也被修改
        buffer.rewind();
        System.out.println("修改后的第一个整数: " + buffer.getInt());
        
        // 复合使用：通过视图高效处理数组数据
        int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        ByteBuffer byteBuffer = ByteBuffer.allocate(intArray.length * 4);
        IntBuffer ib = byteBuffer.asIntBuffer();
        ib.put(intArray);  // 将整个数组放入缓冲区
        
        // 读取验证
        ib.flip();
        System.out.println("\n通过IntBuffer读取的整数数组: ");
        while (ib.hasRemaining()) {
            System.out.print(ib.get() + " ");
        }
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">视图缓冲区可以大大简化对特定数据类型的操作，提高代码可读性和性能。</p>
                </div>
            </div>
        </section>

        <!-- 应用部分 -->
        <section id="applications" class="mb-16">
            <div class="flex items-center mb-8">
                <h2 class="text-3xl font-bold">四、ByteBuffer在网络编程和文件IO中的应用</h2>
                <div class="ml-4 px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full text-sm font-medium">实战应用</div>
            </div>

            <!-- 网络编程 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">1</span>
                    使用ByteBuffer进行网络编程
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer与Channel结合是NIO网络编程的核心。下面是一个简单的NIO服务器示例：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOEchoServer {
    public static void main(String[] args) throws IOException {
        // 创建选择器
        Selector selector = Selector.open();
        
        // 创建服务器通道
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(new InetSocketAddress(8080));
        
        // 注册到选择器，关注连接事件
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        
        System.out.println("NIO Echo服务器启动，监听端口：8080");
        
        ByteBuffer buffer = ByteBuffer.allocate(256);
        
        while (true) {
            // 阻塞等待就绪的通道
            selector.select();
            
            // 获取就绪通道的集合
            Set&lt;SelectionKey&gt; selectedKeys = selector.selectedKeys();
            Iterator&lt;SelectionKey&gt; iter = selectedKeys.iterator();
            
            while (iter.hasNext()) {
                SelectionKey key = iter.next();
                
                if (key.isAcceptable()) {
                    // 接受新连接
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    SocketChannel client = server.accept();
                    
                    if (client != null) {
                        client.configureBlocking(false);
                        // 注册读事件
                        client.register(selector, SelectionKey.OP_READ);
                        System.out.println("接受新客户端连接: " + client.getRemoteAddress());
                    }
                } else if (key.isReadable()) {
                    // 读取数据
                    SocketChannel client = (SocketChannel) key.channel();
                    buffer.clear();
                    
                    int bytesRead = client.read(buffer);
                    if (bytesRead > 0) {
                        buffer.flip();
                        byte[] data = new byte[buffer.limit()];
                        buffer.get(data);
                        String message = new String(data).trim();
                        
                        System.out.println("收到: " + message);
                        
                        // 回显数据
                        buffer.clear();
                        buffer.put(("Echo: " + message).getBytes());
                        buffer.flip();
                        client.write(buffer);
                    } else if (bytesRead < 0) {
                        // 客户端断开连接
                        System.out.println("客户端断开连接: " + client.getRemoteAddress());
                        client.close();
                    }
                }
                
                // 处理完毕，从集合中移除
                iter.remove();
            }
        }
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个示例展示了如何使用ByteBuffer在NIO网络编程中读写数据。NIO服务器支持高并发连接，是高性能网络应用的基础。</p>
                </div>
            </div>

            <!-- 文件操作 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">2</span>
                    使用ByteBuffer进行文件操作
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">ByteBuffer同样适用于高效的文件读写操作：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class FileChannelDemo {
    public static void main(String[] args) {
        String filePath = "test_file.txt";
        String content = "这是一个使用FileChannel和ByteBuffer进行文件操作的示例。\n我们将展示如何高效地读写文件。";

        // 写入文件
        try (FileChannel channel = FileChannel.open(
                Paths.get(filePath),
                StandardOpenOption.CREATE,
                StandardOpenOption.WRITE)) {
            
            ByteBuffer buffer = ByteBuffer.wrap(content.getBytes());
            
            int bytesWritten = 0;
            while (buffer.hasRemaining()) {
                bytesWritten += channel.write(buffer);
            }
            
            System.out.println("写入完成，共写入 " + bytesWritten + " 字节");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 读取文件
        try (FileChannel channel = FileChannel.open(
                Paths.get(filePath),
                StandardOpenOption.READ)) {
            
            // 获取文件大小
            long fileSize = channel.size();
            System.out.println("文件大小: " + fileSize + " 字节");
            
            // 创建缓冲区
            ByteBuffer buffer = ByteBuffer.allocate((int) fileSize);
            
            // 读取文件内容
            int bytesRead = channel.read(buffer);
            System.out.println("读取了 " + bytesRead + " 字节");
            
            // 准备读取缓冲区数据
            buffer.flip();
            
            // 将缓冲区内容转换为字符串
            byte[] data = new byte[buffer.limit()];
            buffer.get(data);
            String fileContent = new String(data);
            
            System.out.println("文件内容:");
            System.out.println(fileContent);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 使用内存映射文件进行大文件处理
        try {
            String largeFilePath = "large_file.dat";
            
            // 创建一个100MB的大文件
            System.out.println("\n创建100MB的测试文件...");
            try (FileChannel channel = FileChannel.open(
                    Paths.get(largeFilePath),
                    StandardOpenOption.CREATE,
                    StandardOpenOption.WRITE)) {
                
                // 设置文件大小
                channel.truncate(100 * 1024 * 1024); // 100MB
                
                // 使用内存映射处理文件
                System.out.println("使用内存映射写入数据...");
                ByteBuffer mappedBuffer = channel.map(
                        FileChannel.MapMode.READ_WRITE, 0, channel.size());
                
                // 每隔1MB写入一个整数
                for (int i = 0; i < 100; i++) {
                    mappedBuffer.position(i * 1024 * 1024);
                    mappedBuffer.putInt(i);
                }
                
                System.out.println("内存映射写入完成");
            }
            
            // 读取验证
            System.out.println("使用内存映射读取数据...");
            try (FileChannel channel = FileChannel.open(
                    Paths.get(largeFilePath),
                    StandardOpenOption.READ)) {
                
                ByteBuffer mappedBuffer = channel.map(
                        FileChannel.MapMode.READ_ONLY, 0, channel.size());
                
                // 验证数据，读取前5个写入的值
                for (int i = 0; i < 5; i++) {
                    mappedBuffer.position(i * 1024 * 1024);
                    System.out.println("位置 " + (i * 1024 * 1024) + " 的值: " + mappedBuffer.getInt());
                }
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个例子演示了如何使用ByteBuffer和FileChannel进行常规文件操作，以及如何使用内存映射文件技术处理大文件，这在处理大型数据集时特别有效。</p>
                </div>
            </div>

            <!-- HTTP客户端 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 flex items-center">
                    <span class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-3">3</span>
                    实现简单的HTTP客户端
                </h3>
                <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
                    <p class="mb-4">下面是一个使用ByteBuffer实现的简单HTTP客户端示例：</p>
                    
                    <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                        <pre class="text-gray-100"><code>import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;

public class SimpleHttpClient {
    public static void main(String[] args) {
        String hostname = "www.example.com";
        int port = 80;
        
        try {
            // 打开Socket通道
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress(hostname, port));
            
            // 构建HTTP请求
            String request = "GET / HTTP/1.1\r\n" +
                             "Host: " + hostname + "\r\n" +
                             "Connection: close\r\n\r\n";
            
            ByteBuffer requestBuffer = ByteBuffer.wrap(request.getBytes(StandardCharsets.UTF_8));
            
            // 发送请求
            System.out.println("发送HTTP请求...");
            while (requestBuffer.hasRemaining()) {
                socketChannel.write(requestBuffer);
            }
            
            // 读取响应
            System.out.println("读取HTTP响应...");
            ByteBuffer responseBuffer = ByteBuffer.allocate(8192);
            StringBuilder response = new StringBuilder();
            
            int bytesRead;
            while ((bytesRead = socketChannel.read(responseBuffer)) > 0) {
                responseBuffer.flip();
                response.append(StandardCharsets.UTF_8.decode(responseBuffer));
                responseBuffer.clear();
            }
            
            // 关闭通道
            socketChannel.close();
            
            // 处理响应
            String httpResponse = response.toString();
            String[] parts = httpResponse.split("\r\n\r\n", 2);
            
            System.out.println("HTTP响应头:");
            System.out.println(parts[0]);
            
            if (parts.length > 1) {
                System.out.println("\nHTTP响应体 (前100字符):");
                System.out.println(parts[1].substring(0, Math.min(100, parts[1].length())) + "...");
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}</code></pre>
                    </div>
                    <p class="text-gray-600 text-sm">这个示例展示了如何使用ByteBuffer和SocketChannel实现一个基本的HTTP客户端，这是NIO网络编程的典型应用场景。</p>
                </div>
            </div>
        </section>
    </main>

    <!-- 页脚 -->
    <footer class="bg-gray-900 text-white py-8">
        <div class="container mx-auto px-4">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <div class="flex items-center space-x-2">
                        <i class="fas fa-code text-2xl text-indigo-400"></i>
                        <span class="font-semibold text-xl">技术小馆</span>
                    </div>
                    <p class="text-gray-400 mt-2">探索技术，分享知识</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-indigo-400 hover:text-indigo-300 transition flex items-center">
                        <i class="fas fa-book-open mr-2"></i>
                        <span>访问语雀文档</span>
                    </a>
                    <p class="text-gray-400 mt-2 text-sm">© 2023 技术小馆 版权所有</p>
                </div>
            </div>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```